package address_logic

import (
	"context"
	"errors"
	"fmt"
	"wx-uniapp-go/internal/repository/dto"
	"wx-uniapp-go/internal/repository/models"
)

type AddressLogic struct {
	Ctx context.Context
}

func NewAddressLogic(ctx context.Context) *AddressLogic {
	return &AddressLogic{Ctx: ctx}
}

// CreateAddress 创建收货地址
func (l *AddressLogic) CreateAddress(userId int64, req *dto.CreateAddressReq) error {
	// 如果设置为默认地址，需要将其他地址设置为非默认
	if req.IsDefault == 1 {
		err := l.resetDefaultAddress(userId)
		if err != nil {
			return err
		}
	}

	// 创建地址
	address := &models.UserAddress{
		UserId:       userId,
		Name:         req.Name,
		Mobile:       req.Mobile,
		ProvinceCode: req.ProvinceCode,
		ProvinceName: req.ProvinceName,
		CityCode:     req.CityCode,
		CityName:     req.CityName,
		DistrictCode: req.DistrictCode,
		DistrictName: req.DistrictName,
		Address:      req.Address,
		HouseNumber:  req.HouseNumber,
		PostCode:     req.PostCode,
		Tag:          req.Tag,
		IsDefault:    req.IsDefault,
		Status:       models.AddressStatusNormal,
	}

	// 如果未设置标签，使用默认标签
	if address.Tag == "" {
		address.Tag = models.AddressTagOther
	}

	_, err := models.Insert(l.Ctx, address)
	return err
}

// UpdateAddress 更新收货地址
func (l *AddressLogic) UpdateAddress(userId int64, req *dto.UpdateAddressReq) error {
	// 查询地址是否存在
	address := new(models.UserAddress)
	exists, err := models.Get(l.Ctx, address, "id = ? AND user_id = ?", req.Id, userId)
	if err != nil {
		return err
	}
	if !exists {
		return errors.New("地址不存在")
	}

	// 如果设置为默认地址，需要将其他地址设置为非默认
	if req.IsDefault == 1 && address.IsDefault != 1 {
		err := l.resetDefaultAddress(userId)
		if err != nil {
			return err
		}
	}

	// 更新字段
	if req.Name != "" {
		address.Name = req.Name
	}
	if req.Mobile != "" {
		address.Mobile = req.Mobile
	}
	if req.ProvinceCode != "" {
		address.ProvinceCode = req.ProvinceCode
	}
	if req.ProvinceName != "" {
		address.ProvinceName = req.ProvinceName
	}
	if req.CityCode != "" {
		address.CityCode = req.CityCode
	}
	if req.CityName != "" {
		address.CityName = req.CityName
	}
	if req.DistrictCode != "" {
		address.DistrictCode = req.DistrictCode
	}
	if req.DistrictName != "" {
		address.DistrictName = req.DistrictName
	}
	if req.Address != "" {
		address.Address = req.Address
	}
	if req.HouseNumber != "" {
		address.HouseNumber = req.HouseNumber
	}
	if req.PostCode != "" {
		address.PostCode = req.PostCode
	}
	if req.Tag != "" {
		address.Tag = req.Tag
	}
	if req.IsDefault > 0 {
		address.IsDefault = req.IsDefault
	}
	if req.Status > 0 {
		address.Status = req.Status
	}

	return models.Update(l.Ctx, fmt.Sprintf("id = %d", req.Id), address)
}

// DeleteAddress 删除收货地址
func (l *AddressLogic) DeleteAddress(userId int64, id int64) error {
	// 查询地址是否存在
	address := new(models.UserAddress)
	exists, err := models.Get(l.Ctx, address, "id = ? AND user_id = ?", id, userId)
	if err != nil {
		return err
	}
	if !exists {
		return errors.New("地址不存在")
	}

	return models.Delete(l.Ctx, &models.UserAddress{Id: id}, "")
}

// ListAddress 查询收货地址列表
func (l *AddressLogic) ListAddress(userId int64, req *dto.ListAddressReq) (*dto.ListAddressResp, error) {
	where := "user_id = ?"
	var params []interface{}
	params = append(params, userId)

	if req.Status > 0 {
		where += " AND status = ?"
		params = append(params, req.Status)
	}

	var addresses []*models.UserAddress
	err := models.Find(l.Ctx, &addresses, where, params...)
	if err != nil {
		return nil, err
	}

	// 转换响应
	list := make([]*dto.AddressResp, len(addresses))
	for i, address := range addresses {
		list[i] = &dto.AddressResp{
			Id:           address.Id,
			Name:         address.Name,
			Mobile:       address.Mobile,
			ProvinceCode: address.ProvinceCode,
			ProvinceName: address.ProvinceName,
			CityCode:     address.CityCode,
			CityName:     address.CityName,
			DistrictCode: address.DistrictCode,
			DistrictName: address.DistrictName,
			Address:      address.Address,
			HouseNumber:  address.HouseNumber,
			PostCode:     address.PostCode,
			Tag:          address.Tag,
			IsDefault:    address.IsDefault,
			Status:       address.Status,
		}
	}

	return &dto.ListAddressResp{List: list}, nil
}

// resetDefaultAddress 重置默认地址
func (l *AddressLogic) resetDefaultAddress(userId int64) error {
	address := &models.UserAddress{
		IsDefault: 0,
	}
	return models.Update(l.Ctx, fmt.Sprintf("user_id = %d AND is_default = 1", userId), address)
}
